package org.budo.freemarker.spring.mvc.view;

import java.io.IOException;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.budo.support.mvcs.Mvcs;
import org.budo.support.slf4j.Slf4j;
import org.slf4j.Logger;
import org.springframework.web.servlet.view.freemarker.FreeMarkerView;

import freemarker.ext.beans.BeansWrapperBuilder;
import freemarker.template.Configuration;
import freemarker.template.SimpleHash;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateHashModel;

/**
 * @author limingwei
 * @see org.budo.freemarker.spring.mvc.view.BudoFreeMarkerViewResolver
 * @see org.budo.freemarker.spring.mvc.view.BudoFreeMarkerConfigurer
 */
public class BudoFreeMarkerView extends FreeMarkerView {
    private static final Logger log = Slf4j.getLogger();

    private static final TemplateHashModel STATIC_MODELS = new BeansWrapperBuilder(Configuration.getVersion()).build().getStaticModels();

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception {
        model.put("def", STATIC_MODELS); // 静态方法调用支持,类似${def["java.lang.System"].currentTimeMillis()}

        super.render(model, request, response);
    }

    protected Template getTemplate(String name, Locale locale) throws IOException {
        Template template = super.getTemplate(name, locale);
        if (null == template) {
            log.error("template is null, name=" + name);
        }
        return template;
    }

    protected void doRender(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
        try {
            super.doRender(model, request, response);
        } catch (Throwable e) {
            throw new RuntimeException("e=" + e + ", model=" + model + ", request=" + request + ", serverName=" + request.getServerName()
            +", requestAttributeMap="+Mvcs.getRequestAttributeMap(request)
            + ", response=" + response, e);
        }
    }

    protected void processTemplate(Template template, SimpleHash model, HttpServletResponse response) throws IOException, TemplateException {
        try {
            super.processTemplate(template, model, response);
        } catch (Throwable e) {
            throw new RuntimeException("e=" + e + ", template=" + template + ", model=" + model + ", request=" + Mvcs.getRequest() + ", response=" + response, e);
        }
    }
}
